package cn.cmcc.online.smsapi.ui.web;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import cn.cmcc.online.smsapi.ui.R;
import cn.cmcc.online.smsapi.ui.model.ActionData;
import cn.cmcc.online.smsapi.ui.util.DataExchangeProxy;
import cn.cmcc.online.smsapi.ui.web.impl.BaseActivityForWebViewImpl;
import cn.cmcc.online.smsapi.ui.web.data.MenuData;
import cn.cmcc.online.smsapi.ui.web.widget.SdkWebView;

public class SdkWebActivity extends AppCompatActivity implements OnClickListener {

    private static final String TAG = SdkWebActivity.class.getSimpleName();
    private static final int CONFIG_WEB_TOP_MENU = 2;

    private SdkWebView mWebView = null;
    private RelativeLayout mViewWebView, mViewError, mViewNetworkSetting;
    private ProgressBar mProgressBar;
    private Toolbar mToolbar;

    private String mEndUrl = "";
    private String mActionType = "";
    private JSONArray mMenuDataArr = null;

    private IActivityParamForJS mActivityParamForJS;

    private static AtomicInteger atomicCount = new AtomicInteger();


    @SuppressLint("JavascriptInterface")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sdk_web);

        initView();
        atomicCount.incrementAndGet();
        mActivityParamForJS = getSdkWebViewManager();
        if (mActivityParamForJS != null) {
            mActionType = mActivityParamForJS.getParamData("type");
        }
    }

    private void initView() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setTitle("");
        setSupportActionBar(mToolbar);
        mToolbar.setNavigationIcon(R.drawable.ic_webview_back);
        mToolbar.setNavigationOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mViewWebView = (RelativeLayout) findViewById(R.id.view_webview);
        mWebView = new SdkWebView(getApplicationContext());
        mViewWebView.addView(mWebView);
        mWebView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        //TODO debug test
//        mWebView.setWebContentsDebuggingEnabled(true);
        mViewError = (RelativeLayout) findViewById(R.id.view_error_page);
        mViewNetworkSetting = (RelativeLayout) findViewById(R.id.view_network_setting);
        mViewNetworkSetting.setOnClickListener(this);
        mProgressBar = (ProgressBar) findViewById(R.id.progressbar);
    }

    private IActivityParamForJS getSdkWebViewManager() {
        ActivityForWebViewImpl activityForWebViewImp = new ActivityForWebViewImpl();
        return DataExchangeProxy.getInstance().getJSManager(activityForWebViewImp);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mActivityParamForJS.doDestroy();
        mViewWebView.removeAllViews();
        mWebView.destroy();
        int count = atomicCount.decrementAndGet();
        int pid = android.os.Process.myPid();
        String processName = getCurProcessName(pid);
        if (count == 0 && "com.xy.web".equals(processName)) {
            android.os.Process.killProcess(pid);
        }
    }

    private String getCurProcessName(int pid) {
        try {
            ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            if (mActivityManager == null) {
                return "";
            }
            List<RunningAppProcessInfo> runAppList = mActivityManager
                    .getRunningAppProcesses();
            if (runAppList == null) {
                return "";
            }
            for (ActivityManager.RunningAppProcessInfo appProcess : runAppList) {
                if (appProcess.pid == pid) {
                    return appProcess.processName;
                }
            }
        } catch (Throwable e) {
        }
        return "";
    }

    public void setTitle(String title, String menuName) {
        setTitle(TextUtils.isEmpty(menuName) ? title : menuName);
        mToolbar.setTitle(TextUtils.isEmpty(menuName) ? title : menuName);
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            if (mWebView.canGoBack()) {
                mWebView.goBack();
            } else {
                finish();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * Error page
     */
    void errorPage() {
        mProgressBar.setVisibility(View.GONE);
        mWebView.setVisibility(View.GONE);
        mToolbar.setTitle(R.string.web_not_find_page);
        mViewError.setVisibility(View.VISIBLE);
    }

    public void setParamData(String key, String value) {
        mActivityParamForJS.setParamData(key, value);
    }

    private void initMenuView() {
        if (!DataExchangeProxy.getInstance().geOnOffByType(CONFIG_WEB_TOP_MENU)) {
            return;
        }

        mMenuDataArr = DataExchangeProxy.getInstance().getConfigByType(CONFIG_WEB_TOP_MENU,
                MenuData.UI_VERSION, MenuData.SUPPORT_STATE);
        if (mMenuDataArr == null || mMenuDataArr.length() == 0) {
            mMenuDataArr = MenuData.getDefaultMenuData();
        }

        mMenuDataArr = filterMenu(mMenuDataArr);
    }

    private JSONArray filterMenu(JSONArray menuDataArr) {
        if (TextUtils.isEmpty(mActionType) || menuDataArr == null) {
            return menuDataArr;
        }

        JSONArray newMenu = new JSONArray();
        for (int i = 0; i < menuDataArr.length(); i++) {
            JSONObject menuData = menuDataArr.optJSONObject(i);
            if (menuData != null && !mActionType.equals(menuData.opt("type"))) {
                newMenu.put(menuData);
            }
        }

        return newMenu;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.view_network_setting) {
            Intent intent;
            try {
                String sdkVersion = android.os.Build.VERSION.SDK;
                if (Integer.valueOf(sdkVersion) > 10) {
                    intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
                } else {
                    intent = new Intent();
                    ComponentName comp = new ComponentName("com.android.settings",
                            "com.android.settings.WirelessSettings");
                    intent.setComponent(comp);
                    intent.setAction("android.intent.action.VIEW");
                }
                SdkWebActivity.this.startActivity(intent);
            } catch (Throwable e) {
                Log.e("SdkWebActivity error ", e.toString());
            }
        }
    }

    private class ActivityForWebViewImpl extends BaseActivityForWebViewImpl {
        @Override
        public WebView getWebView() {
            return mWebView;
        }

        @Override
        public Activity getActivity() {
            return SdkWebActivity.this;
        }

        @Override
        public Intent getIntent() {
            return SdkWebActivity.this.getIntent();
        }

        @Override
        public int checkOrientation() {
            int currentOrientation = getResources().getConfiguration().orientation;
            return currentOrientation;
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url != null
                    && !url.toLowerCase(Locale.getDefault()).startsWith(
                    "http")) {
                try {
                    if (url.indexOf("tel:") >= 0) {
                        Intent intent = new Intent(Intent.ACTION_DIAL, Uri
                                .parse(url));
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    } else {
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setData(Uri.parse(url));
                        startActivity(intent);
                    }
                } catch (Throwable e) {
                    Log.e("SdkWebActivity error ", e.toString());
                }
                return true;
            }
            return false;
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                mProgressBar.setVisibility(View.GONE);
            } else {
                if (View.GONE == mProgressBar.getVisibility()) {
                    mProgressBar.setVisibility(View.VISIBLE);
                }
                mProgressBar.setProgress(newProgress);
            }
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            mViewError.setVisibility(View.GONE);
            mWebView.setVisibility(View.VISIBLE);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            mWebView.getSettings().setBlockNetworkImage(false);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            if (errorCode != -10) {
                view.stopLoading();
                view.clearView();
                errorPage();
                mEndUrl = failingUrl;
            }
        }

        @Override
        public void showError(int errorCode, Map<String, Object> extend) {
            mProgressBar.setVisibility(View.GONE);
            mWebView.setVisibility(View.GONE);
            mToolbar.setTitle(R.string.web_not_find_page);
            mViewError.setVisibility(View.VISIBLE);
        }

        @Override
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
                                    long contentLength) {
            Uri uri = Uri.parse(url);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }

        @Override
        public void setEndUrl(String url) {
            mEndUrl = url;
        }

        @Override
        public void requestWebViewLoad(String pageViewUrl) {
            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.GONE);
            }
            if (mWebView != null) {
                mWebView.loadUrl(pageViewUrl);
            }
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
            Builder builder = new Builder(SdkWebActivity.this);
            builder.setTitle("Alert");
            builder.setMessage(message);
            builder.setPositiveButton(android.R.string.ok,
                    new AlertDialog.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            result.confirm();
                        }
                    });
            builder.setCancelable(false);
            builder.create();
            builder.show();
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
            Builder builder = new Builder(SdkWebActivity.this);
            builder.setTitle("confirm");
            builder.setMessage(message);
            builder.setPositiveButton(android.R.string.ok,
                    new AlertDialog.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            result.confirm();
                        }
                    });
            builder.setNegativeButton(android.R.string.cancel,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            result.cancel();
                        }
                    });
            builder.setCancelable(false);
            builder.create();
            builder.show();
            return true;
        }

        @Override
        public boolean onConsoleMessage(ConsoleMessage cm) {
            return true;
        }

        @Override
        public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
            callback.invoke(origin, true, false);
        }

        @Override
        public void onConsoleMessage(String message, int lineNumber, String sourceID) {

        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            String menuName = mActivityParamForJS.getParamData("menuName");
            setTitle(title, menuName);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        initMenuView();
        if (mMenuDataArr != null && mMenuDataArr.length() > 0) {
            getMenuInflater().inflate(R.menu.menu_web, menu);
        }
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // 动态设置ToolBar状态
        if (mMenuDataArr != null && mMenuDataArr.length() > 0) {
            for (int i = 0; i < mMenuDataArr.length(); i++) {
                try {
                    JSONObject jSONObject = mMenuDataArr.getJSONObject(i);
                    String title = jSONObject.optString("name");
                    if (!TextUtils.isEmpty(title) && i == 0) {
                        menu.findItem(R.id.action_first).setVisible(true).setTitle(title);
                    }
                    if (!TextUtils.isEmpty(title) && i == 1) {
                        menu.findItem(R.id.action_second).setVisible(true).setTitle(title);
                    }

                } catch (Throwable e) {
                    Log.e(TAG, "onPrepareOptionsMenu, e = " + e);
                }
            }
        }
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        JSONObject jSONObject = null;
        try {
            if (id == R.id.action_first) {
                jSONObject = mMenuDataArr.getJSONObject(0);
            } else if (id == R.id.action_second) {
                jSONObject = mMenuDataArr.getJSONObject(1);
            }
            if (jSONObject != null) {
                if (!TextUtils.isEmpty(jSONObject.optString("web_menu_type"))) {
                    menuDoActionContext(jSONObject);
                } else {
                    ActionData actionData = new ActionData(jSONObject.optString("name"), jSONObject.optString("type"), jSONObject.get("action_data").toString());
                    DataExchangeProxy.getInstance().processAction(this, actionData);
                }
                return true;
            }
        } catch (Throwable e) {
            Log.e(TAG, "onPrepareOptionsMenu, e = " + e);
        }
        return super.onOptionsItemSelected(item);
    }

    private void menuDoActionContext(JSONObject jsobj) {
        String webMenuType = jsobj.optString("web_menu_type");
        if (webMenuType.toUpperCase().equals("WM_RELOAD")) {
            reloadWebView();
        }
    }

    private void reloadWebView() {
        WebView webView = (WebView) mViewWebView.getChildAt(0);
        int isNetWork = DataExchangeProxy.getInstance().checkNetWork(getApplicationContext(), 2);
        if (isNetWork == -1 || isNetWork == 1) {
            mViewError.setVisibility(View.VISIBLE);
            mToolbar.setTitle(R.string.web_not_find_page);
            webView.setVisibility(View.GONE);
        } else {
            if (!TextUtils.isEmpty(mEndUrl)) {
                webView.loadUrl(mEndUrl);
                mEndUrl = "";
            } else {
                webView.reload();
            }
            mViewError.setVisibility(View.GONE);
            webView.setVisibility(View.VISIBLE);
        }
    }
}
